<template>
  <FModal ref="refFModal" width="1000" header="部门管理">
    <FPage class="depart-manager-page" v-loading="loading">
      <template #header>
        <div style="padding: 5px 5px">
          <el-button type="primary" icon="add" round @click="addNew">新建</el-button>
          <el-button type="warning" icon="remove" round>删除</el-button>
          <el-button icon="user" round @click="showDepartUserModal"
                     :disabled="isEmpty(departData)">查看人员</el-button>
        </div>
      </template>

      <div class="depart-manager-wrapper">
        <div class="depart-manager-left">
          <el-tree
              node-key="id" check-on-click-node check-strictly
              :expand-on-click-node="false" show-checkbox @checkChange="checkChange"
              auto-expand-parent ref="refUnitTree" @check="onCheck"
              class="filter-tree" :data="unitTrees" :indent="5"
              :props="defaultProps" default-expand-all @node-click="departSelectChange"
              :filter-node-method="filterNode">
          </el-tree>
        </div>
        <div style="width: 10px"/>
        <div class="depart-manager-right">
          <div style="margin: 10px; padding-right: 80px" v-if="departData">
            <el-form ref="refForm" label-width="120px" :model="departData">
              <el-text truncated tag="b">
                部门基本信息
              </el-text>
              <el-form-item prop="unitName" label="部门名称" :rules="[required]">
                <el-input placeholder="请输入部门名称" v-model="departData.unitName"/>
              </el-form-item>

              <el-form-item prop="unitCode" label="部门代码" :rules="[required]">
                <el-input placeholder="请输入部门代码" v-model="departData.unitCode"/>
              </el-form-item>

              <el-form-item prop="unitCode" label="排序号" :rules="[required]">
                <el-input-number style="width: 100%" placeholder="请输入排序号"
                                 v-model="departData.sort"/>
              </el-form-item>

              <el-form-item prop="parentId" label="上级部门" :rules="[required]">
                <el-tree-select style="width: 100%" :props="defaultProps"
                                v-model="departData.parentId" @change="parentChange"
                                :data="parentSelectData" default-expand-all
                                check-strictly node-key="id"
                                :render-after-expand="false"
                />
              </el-form-item>

              <el-form-item prop="parentId" label="状态" :rules="[required]">
                <SystemDict dict-code="unitStatus" placeholder="请选择状态"
                            v-model="departData.unitStatus"/>
              </el-form-item>

              <el-form-item prop="positionNames" v-if="isNotEmpty(departData.id)"
                            label="部门岗位" :rules="[]">
                <el-input type="textarea" @click="showDepartUserModal" style="cursor: pointer"
                          v-model="departData.departPositionNames" readonly/>
              </el-form-item>

              <template v-if="isNotEmpty(departData.departRoles)">
                <el-text truncated tag="b">
                  部门角色信息
                </el-text>

                <el-form-item v-for="departRole in departData.departRoles"
                              prop="branchLeaderId" :label="departRole.roleName" :rules="[]">
                  <MultiUserSelector v-model:usersId="departRole.userIds"
                                     :tabsConfig="userSelectTabsConfig"
                                     v-model:usersName="departRole.userNames"/>
                </el-form-item>
              </template>
            </el-form>
          </div>
        </div>
      </div>
    </FPage>

    <template #footer>
      <el-button round type="warning" icon="close" @click="cancel">关闭</el-button>
      <el-button round type="primary" v-show="isNotEmpty(departData)"
                 icon="save" @click="saveDepart">保存
      </el-button>
    </template>
  </FModal>
  <UserManageModal ref="refUserManageModal"/>
</template>
<script setup>
import FModal from '@/components/FModal/index.vue';
import {computed, nextTick, ref, shallowRef} from 'vue';
import {getAction, postAction} from '@/request/BaseRequest';
import {isEmpty, isNotEmpty, listToTrees, real, required, treesForeach} from '@/utils/CommonUtils';
import FPage from '@/components/layout/FPage.vue';
import SystemDict from '@/components/SystemDict';
import MultiUserSelector from '@/components/MultiUserSelector/index.vue';
import {ElMessage} from 'element-plus';
import UserManageModal from '@/views/system/UnitManagement/UserManageModal/index.vue';

const refUserManageModal = shallowRef();
const refFModal = shallowRef();
const refUnitTree = shallowRef();
let unitData = undefined;
const unitTrees = shallowRef([]);
const loading = shallowRef(false);
const defaultProps = {
  children: 'children',
  label: 'unitName',
};
const refForm = shallowRef();
const departData = ref();
const userSelectTabsConfig = shallowRef([
  {name: 'depart'},
  {name: 'position'},
  {name: 'positionLevel'}
]);

function addNew() {
  departData.value = createDefaultDepart();
}

function createDefaultDepart() {
  getAction('/sys/unit/loadMaxUnitSort').then(data => {
    if (data.success) {
      departData.value.sort = data.result;
    }
  });
  let parentId = unitData.id;
  let nodes = refUnitTree.value.getCheckedNodes();
  if (!isEmpty(nodes)) parentId = nodes[0].id;

  return {
    parentId,
    unitStatus: '0'
  };
}

function filterNode(value, data) {
  if (!value) return true;
  return data.unitName.includes(value);
}

function onCheck(data) {
  let node = refUnitTree.value.getCheckedNodes();
  if (!isEmpty(node)) {
    refUnitTree.value.setCheckedKeys([data.id]);
  }
}

function departSelectChange(node) {
  node = real(node);
  refUnitTree.value.setCheckedKeys([node.id]);
}

function checkChange() {
  let nodes = refUnitTree.value.getCheckedNodes();
  if (isEmpty(nodes)) {
    departData.value = undefined;
  } else {
    if (nodes[0].id === unitData.id) {
      departData.value = undefined;
      return;
    }
    loadDepartById(nodes[0].id);
  }
}

function showDepartUserModal() {
  let depart = real(departData);
  refUserManageModal.value.setData(unitData);
  nextTick(() => {
    refUserManageModal.value.departSelectChange(depart);
  })
}

function parentChange() {
  let parentId = departData.value.parentId;
  let currentNode = null;
  treesForeach(real(unitTrees), node => {
    node = real(node);
    if (node.id === departData.value.id) {
      currentNode = node;
    }
  });

  let trees = [currentNode];
  let flag = false;
  treesForeach(trees, node => {
    if (node.id === parentId) {
      flag = true;
    }
  });
  if (flag) {
    departData.value.parentId = undefined;
    ElMessage({
      message: '请勿将当前部门或者下级部门设置为上级部门',
      type: 'warning',
    });
  }
}

function loadDepartById(id) {
  loading.value = true;
  getAction('/sys/unit/loadDepartById',
      {id}).then(data => {
    loading.value = false;
    if (data.success) {
      departData.value = data.result;
    }
  });
}

function setData(_unitData) {
  unitData = real(_unitData);
  refFModal.value.open();
  nextTick(() => {
    refUnitTree.value.setCheckedKeys([]);
  });
  departData.value = undefined;
  loadUnitsByPath();
}

function loadUnitsByPath(callback) {
  loading.value = true;
  getAction('/sys/unit/loadDepatrsByPath',
      {path: unitData.path}).then(data => {
    loading.value = false;
    if (data.success) {
      let result = data.result;
      setUnitTrees(result);
      if (callback) callback();
    }
  });
}

function setUnitTrees(list) {
  let trees = listToTrees(list);
  if (isEmpty(trees)) {
    trees = [];
  }
  unitTrees.value = trees;
}

function cancel() {
  refFModal.value.close();
}

function saveDepart() {
  refForm.value.validate((valid, errors) => {
    if (valid) {
      let _departData = real(departData);
      doSaveDepart(_departData);
    }
  });
}

function doSaveDepart(departData) {
  loading.value = true;
  postAction('/sys/unit/saveDepart', departData).then(data => {
    loading.value = false;
    if (data.success) {
      let result = data.result;
      loadUnitsByPath(() => {
        refUnitTree.value.setCheckedKeys([result.id]);
        loadDepartById(result.id);
      });
    }
  });
}

const parentSelectData = computed(() => {
  return real(unitTrees);
});

defineExpose({
  setData
});
</script>
<script>
export default {
  name: 'DepartManagerModal'
};
</script>
<style>
.depart-manager-wrapper {
  display: flex;
  width: 100%;
}

.f-modal-body .depart-manager-wrapper {
  flex: 1;
  height: 600px;
  background: white;
}

.f-modal-fullscreen-body .depart-manager-wrapper {
  flex: 1;
  height: 100%;
}

.depart-manager-wrapper .depart-manager-left {
  width: 260px;
  height: 100%;
  overflow: auto;
  border: 1px solid #dcdfe6;
  box-sizing: border-box;
}

.depart-manager-wrapper .depart-manager-right {
  flex: 1;
  height: 100%;
  border: 1px solid #dcdfe6;
  overflow: auto;
  box-sizing: border-box;
}

.depart-manager-page {
  height: 100%;
}
</style>
